#include "model.h"
#include "Engine.h"
#include "gLib.h"
#include "memoryDef.h"
#include "gTriangle.h"


CModel::CModel(CEngine *engine, int vertexNum, gVertex3D *buff, int faceNum, int index[][3])
:m_centerPosX(0),
m_centerPosY(0),
m_centerPosZ(0),
m_rotateX(0),
m_rotateY(0),
m_rotateZ(0),
m_scaleX(1),
m_scaleY(1),
m_scaleZ(1),
m_color(0),
m_vTransformedBuffer(NULL)
{
	m_engine = engine;
	m_g = m_engine->GetGraphics();

	m_vertexNum = vertexNum;
	m_vOriginalBuffer = NEW gVertex3D[m_vertexNum];
	memcpy(m_vOriginalBuffer, buff, sizeof(gVertex3D)*m_vertexNum);

	m_vTransformedBuffer = NEW gVertex3D[m_vertexNum];
	memset(m_vTransformedBuffer, 0, sizeof(gVertex3D)*m_vertexNum);

	m_vertexState = NEW gVertex3D::VertexState[m_vertexNum];
	memset(m_vertexState, gVertex3D::STATE_UNSETTLED, sizeof(gVertex3D::VertexState)*m_vertexNum);

	m_faceNum = faceNum;
	m_faces = NEW CTriangleIndex[m_faceNum];
	for(int i=0; i<m_faceNum; ++i)
	{
		m_faces[i].SetVertex(m_vTransformedBuffer, index[i]);
	}
}

CModel::~CModel()
{
	SAFE_DELETE_ARRAY(m_vOriginalBuffer);
	SAFE_DELETE_ARRAY(m_vTransformedBuffer);
	SAFE_DELETE_ARRAY(m_vertexState);
	SAFE_DELETE_ARRAY(m_faces);
}

void CModel::SetColor(unsigned char r, unsigned char g, unsigned char b)
{
	m_color = RGB32(r,g,b);
	m_g->gSetColor(r, g, b);
}

void CModel::SetPos(int x, int y, int z)
{
	m_centerPosX = x;
	m_centerPosY = y;
	m_centerPosZ = z;
}

void CModel::TranslateToWorldCoord()
{
	m_g->gTranslateToWorldCoord(m_vTransformedBuffer, m_vOriginalBuffer, m_vertexNum);
}

void CModel::TranslateToCameraCoord()
{
	m_g->gTranslateToCameraCoord(m_vTransformedBuffer, m_vertexState, m_vertexNum);
}

void CModel::InsertToRenderList()
{
	for(int i=0; i<m_faceNum; ++i)
	{
		if(m_faces[i].m_state == CTriangle::STATE_VISIABLE)
		{
			m_g->gInsertToRenderList(&m_faces[i]);
		}
	}
}

void CModel::TestObjVisibale()
{

}

void CModel::TestFaceVisibale()
{
	for(int i=0; i<m_faceNum; ++i)
	{
		float x = m_vTransformedBuffer[m_faces[i].indexA].m_pos.x;
		float y = m_vTransformedBuffer[m_faces[i].indexA].m_pos.y;
		float z = m_vTransformedBuffer[m_faces[i].indexA].m_pos.z;

		CVector3D normal = m_faces[i].CalcNormal();
		CVector3D view = CVector3D(x-m_g->m_camera.m_camPosX, y-m_g->m_camera.m_camPosY, z-m_g->m_camera.m_camPosZ);

		if(normal*view > 0)
		{
			m_faces[i].SetState(CTriangle::STATE_VISIABLE);

			if(m_vertexState[m_faces[i].indexA] == gVertex3D::STATE_UNSETTLED)
				m_vertexState[m_faces[i].indexA] = gVertex3D::STATE_VISIABLE;
			if(m_vertexState[m_faces[i].indexB] == gVertex3D::STATE_UNSETTLED)
				m_vertexState[m_faces[i].indexB] = gVertex3D::STATE_VISIABLE;
			if(m_vertexState[m_faces[i].indexC] == gVertex3D::STATE_UNSETTLED)
				m_vertexState[m_faces[i].indexC] = gVertex3D::STATE_VISIABLE;
		}
		else
		{
			m_faces[i].SetState(CTriangle::STATE_INVISIABLE);
		}
	}
}

void CModel::ResetVertex()
{
	memset(m_vertexState, gVertex3D::STATE_UNSETTLED, sizeof(gVertex3D::VertexState)*m_vertexNum);
}
